package org.example.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import dto.ExceptionTrackingQueryDTO;
import dto.InspectionQualityQueryDTO;
import dto.StandardQuaryDTO;
import entity.*;
import java.util.Arrays;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.example.constant.InspectionConstant;
import org.example.repository.ExceptionTrackingRepository;
import org.example.repository.InspectorRepository;
import org.example.repository.QualityManagerRepository;
import org.example.result.PageResult;
import org.example.result.Result;
import org.example.service.QualityManagerService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vo.QualityInspectionVo;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 质量经理服务实现类
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class QualityManagerServiceImpl implements QualityManagerService {

    private final QualityManagerRepository qualityManagerRepository;

    private final ExceptionTrackingRepository exceptionTrackingRepository;

    private final InspectorRepository inspectorRepository;

    /**
     * 查询质检单
     *
     * @param queryDTO 查询参数
     * @return 分页结果
     */
    @Override
    public PageResult queryQualityInspection(InspectionQualityQueryDTO queryDTO) {
        // 开始分页查询
        PageHelper.startPage(queryDTO.getPageNumber(), queryDTO.getPageSize());
        Page<QualityInspectionVo> qualityInspections = qualityManagerRepository.queryQualityInspection(queryDTO);
        return new PageResult(qualityInspections.getTotal(), qualityInspections.getResult());
    }

    /**
     * 审核质检单
     *
     * @param qualityInspection 质检单信息
     */
    @Override
    @Transactional
    public void reviewQualityInspection(QualityInspection qualityInspection) {
        // 更新质检单状态和处理结果
        qualityManagerRepository.updateQualityInspection(qualityInspection);
        log.info("质检单审核完成：{}", qualityInspection.getInspectionId());
    }

    /**
     * 查询质量标准
     *
     * @param queryDTO 查询参数
     * @return 分页结果
     */
    @Override
    public PageResult queryQualityStandard(StandardQuaryDTO queryDTO) {
        // 确保分页参数正确
        if (queryDTO.getPageNum() == null) {
            queryDTO.setPageNum(1);
        }
        if (queryDTO.getPageSize() == null) {
            queryDTO.setPageSize(10);
        }

        // 查询质量标准列表
        List<QualityStandard> list = qualityManagerRepository.queryQualityStandard(queryDTO);
        // 查询总记录数
        Integer total = qualityManagerRepository.countQualityStandard(queryDTO);
        return new PageResult(total, list);
    }

    /**
     * 获取质量数据看板
     *
     * @return 质量数据看板信息
     */
    @Override
    public Map<String, Object> getQualityDashboard(List<String> dateRange, String inspectionType, String supplier, String defectType) {
        Map<String, Object> dashboard = new HashMap<>();

        // 日期范围处理
        String startDate = null;
        String endDate = null;
        if (dateRange != null && dateRange.size() >= 2) {
            startDate = dateRange.get(0);
            endDate = dateRange.get(1);
            log.info("使用日期范围过滤: {} 至 {}", startDate, endDate);
        }

        // 获取综合合格率
        Map<String, Object> overallPassRate = qualityManagerRepository.getOverallPassRate(startDate, endDate, inspectionType, supplier, defectType);
        dashboard.put("overallPassRate", overallPassRate);

        // 获取质量合格率统计
        Map<String, Object> passRateStats = qualityManagerRepository.getQualityPassRateStats(startDate, endDate, inspectionType, supplier, defectType);
        dashboard.put("passRateStats", passRateStats);

        // 获取不合格批次总数
        Integer unqualifiedCount = qualityManagerRepository.getUnqualifiedCount(startDate, endDate, inspectionType, supplier, defectType);
        Map<String, Object> stats = new HashMap<>();
        stats.put("monthlyExceptionCount", unqualifiedCount);
        stats.put("overallQualifiedTrend", "2%");
        stats.put("overallQualifiedTrendDirection", "up");
        stats.put("monthlyExceptionTrend", "12.5%");
        stats.put("monthlyExceptionTrendDirection", "up");
        stats.put("topDefectSupplier", "深圳光电科技有限公司");
        stats.put("topDefectRate", "2.8%");
        stats.put("topDefectTrend", "0.9%");
        stats.put("topDefectTrendDirection", "down");
        dashboard.put("stats", stats);

        // 获取缺陷类型分布
        List<Map<String, Object>> defectDistribution = qualityManagerRepository.getDefectTypeDistribution(startDate, endDate, inspectionType, supplier);
        dashboard.put("defectDistribution", defectDistribution);

        // 获取原材料合格率趋势
        List<Map<String, Object>> rawMaterialTrend = qualityManagerRepository.getRawMaterialPassRateTrend(startDate, endDate, supplier, defectType);
        dashboard.put("rawMaterialTrend", rawMaterialTrend);

        // 获取半成品合格率趋势
        List<Map<String, Object>> semiFinishedTrend = qualityManagerRepository.getSemiFinishedPassRateTrend(startDate, endDate, supplier, defectType);
        dashboard.put("semiFinishedTrend", semiFinishedTrend);

        // 获取成品合格率趋势
        List<Map<String, Object>> finishedProductTrend = qualityManagerRepository.getFinishedProductPassRateTrend(startDate, endDate, supplier, defectType);
        dashboard.put("finishedProductTrend", finishedProductTrend);

        return dashboard;
    }

    //异常列表
    @Override
    public PageResult getExceptionList(ExceptionTrackingQueryDTO queryDTO) {

        String startDate = null;
        String endDate = null;
        List<String> dateRange = queryDTO.getDateRange();
        if (dateRange != null && dateRange.size() >= 2) {
            startDate = dateRange.get(0);
            endDate = dateRange.get(1);
        }
        queryDTO.setStartDate(startDate);
        queryDTO.setEndDate(endDate);
        PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize());
        Page<ExceptionTracking> exceptions = qualityManagerRepository.queryExceptionTrackings(queryDTO);
        exceptions.setTotal(qualityManagerRepository.dataCount());
        return new PageResult(exceptions.getTotal(), exceptions.getResult());
    }

    //异常跟踪
    @Override
    public List<MaterialOrder> getTracking(String exceptionNumber) {
        //根据exceptionid先获取inspectionid，再根据inspectionid获取materialorderid
        ExceptionTracking exceptionTracking = qualityManagerRepository.getExceptionTrackingByNum(exceptionNumber);
        List<InspectionMaterial> inspectionMaterial = exceptionTrackingRepository.findInspectionMaterialById(exceptionTracking.getInspectionId());

        List<MaterialOrder> materialOrders = new ArrayList<>();
        if (inspectionMaterial != null) {
            for (InspectionMaterial material : inspectionMaterial) {
                materialOrders.add(exceptionTrackingRepository.findMaterialOrderById(material.getMaterialBatchId()));
            }
        }
        return materialOrders;
    }


    //异常详情
    @Override
    public ExceptionTracking getExceptionDetail(String exceptionNumber) {
        return qualityManagerRepository.getExceptionTrackingByNum(exceptionNumber);
    }

    @Override
    public void updateExceptionTracking(ExceptionTracking exceptionTracking) {
        exceptionTracking.setUpdateTime(LocalDateTime.now());
        exceptionTrackingRepository.updateExceptionTracking(exceptionTracking);
    }

    @Override
    public void addExceptionTracking(ExceptionTracking exceptionTracking) {
        exceptionTracking.setCreateTime(LocalDateTime.now());
        exceptionTracking.setUpdateTime(LocalDateTime.now());
        exceptionTracking.setReportTime(LocalDateTime.now());
        exceptionTrackingRepository.addExceptionTracking(exceptionTracking);
    }

    //折线图
    @Override
    public Map<String, Object> getLineChatException() {
        Map<String, Object> LineChart = new HashMap<>();
        LineChart = qualityManagerRepository.getExceptionTrackingTrend();
        return LineChart;
    }


    /**
     * 导出质检单Excel
     *
     * @param inspectionIds 质检单ID列表
     * @param response      响应对象
     */
    @Override
    public void exportInspection(List<Integer> inspectionIds, HttpServletResponse response) {
        try {
            // 1. 根据ID列表查询质检单数据
            List<QualityInspection> inspections = qualityManagerRepository.queryQualityInspectionByIds(inspectionIds);

            // 2. 统计数据
            int totalCount = inspections.size();
            int passCount = Math.toIntExact(inspections.stream().filter(inspection -> "合格".equals(inspection.getInspectResult())).count());
            int failCount = totalCount - passCount;
            int completedCount = Math.toIntExact(inspections.stream().filter(inspection -> "已完成".equals(inspection.getInspectStatus())).count());
            int processingCount = Math.toIntExact(inspections.stream().filter(inspection -> "待处理".equals(inspection.getInspectStatus())).count());
            int rejectCount = Math.toIntExact(inspections.stream().filter(inspection -> "已打回".equals(inspection.getInspectStatus())).count());
            Double percentOfPassRate = (double) passCount / totalCount * 100;

            // 3. 加载Excel模板
            InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/质检数据报表模板.xlsx");
            if (in == null) {
                throw new RuntimeException("Excel模板文件未找到");
            }

            // 4. 基于模板创建Excel对象
            XSSFWorkbook excel = new XSSFWorkbook(in);
            XSSFSheet sheet = excel.getSheetAt(0);

            // 5. 填充概览数据（第4-5行）
            // 质检合格数量
            XSSFRow row4 = sheet.getRow(3); // 第4行（0索引）
            if (row4 == null) row4 = sheet.createRow(3);
            XSSFCell cellC4 = row4.getCell(2);
            if (cellC4 == null) cellC4 = row4.createCell(2);
            cellC4.setCellValue(passCount);

            // 质检不合格数量
            XSSFCell cellE4 = row4.getCell(4);
            if (cellE4 == null) cellE4 = row4.createCell(4);
            cellE4.setCellValue(failCount);

            // 质检已完成数量
            XSSFCell cellG4 = row4.getCell(6);
            if (cellG4 == null) cellG4 = row4.createCell(6);
            cellG4.setCellValue(completedCount);

            // 质检已打回数量（这里用待处理数量代替）
            XSSFRow row5 = sheet.getRow(4); // 第5行
            if (row5 == null) row5 = sheet.createRow(4);
            XSSFCell cellC5 = row5.getCell(2);
            if (cellC5 == null) cellC5 = row5.createCell(2);
            cellC5.setCellValue(rejectCount);

            // 质检待处理数量
            XSSFCell cellE5 = row5.getCell(4);
            if (cellE5 == null) cellE5 = row5.createCell(4);
            cellE5.setCellValue(processingCount);

            //合格率
            XSSFCell cellG5 = row5.getCell(6);
            if (cellG5 == null) cellG5 = row5.createCell(6);
            cellG5.setCellValue(percentOfPassRate);

            // 6. 填充明细数据（从第8行开始）
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            int startRow = 7; // 第8行（0索引）

            for (int i = 0; i < inspections.size(); i++) {
                QualityInspection inspection = inspections.get(i);
                XSSFRow dataRow = sheet.getRow(startRow + i);
                if (dataRow == null) {
                    dataRow = sheet.createRow(startRow + i);
                }

                // 日期
                XSSFCell cellA = dataRow.getCell(1);
                if (cellA == null) cellA = dataRow.createCell(1);
                if (inspection.getCreateTime() != null) {
                    cellA.setCellValue(inspection.getCreateTime().format(formatter));
                }

                // 质检编号
                XSSFCell cellB = dataRow.getCell(2);
                if (cellB == null) cellB = dataRow.createCell(2);
                cellB.setCellValue(inspection.getInspectionId());

                // 文档类型
                XSSFCell cellC = dataRow.getCell(3);
                if (cellC == null) cellC = dataRow.createCell(3);
                cellC.setCellValue(inspection.getInspectType() != null ? inspection.getInspectType() : "");

                // 质检分类
                XSSFCell cellD = dataRow.getCell(4);
                if (cellD == null) cellD = dataRow.createCell(4);
                cellD.setCellValue(inspection.getInspectCategory() != null ? inspection.getInspectCategory() : "");

                // 质检结果
                XSSFCell cellE = dataRow.getCell(5);
                if (cellE == null) cellE = dataRow.createCell(5);
                cellE.setCellValue(inspection.getInspectResult() != null ? inspection.getInspectResult() : "");

                // 状态
                XSSFCell cellF = dataRow.getCell(6);
                if (cellF == null) cellF = dataRow.createCell(6);
                cellF.setCellValue(inspection.getInspectStatus() != null ? inspection.getInspectStatus() : "");
            }

            // 7. 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String encodedFilename = java.net.URLEncoder.encode("质检数据报表.xlsx", "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename + "\"");

            // 8. 通过输出流将Excel下载到浏览器中
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

            // 9. 关闭资源
            outputStream.close();
            excel.close();
            in.close();

            log.info("质检数据报表导出成功，共导出{}条记录", inspections.size());

        } catch (IOException e) {
            log.error("导出质检数据报表失败", e);
            throw new RuntimeException("导出Excel文件失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("导出质检数据报表时发生未知错误", e);
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }

    /**
     * 列出不合格质检列表
     *
     * @return
     */
    @Override
    public List<Integer> listUnqualifiedInspection() {
        return inspectorRepository.listInspection(InspectionConstant.INSPECTION_RESULT_UNQUALIFIED);
    }

    /**
     * 获取异常跟踪时间线
     * @param exceptionNumber 异常编号
     * @return 时间线数据
     */
    @Override
    public List<Map<String, Object>> getTrackingTimeline(String exceptionNumber) {
        List<Map<String, Object>> timeline = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        
        try {
            // 1. 获取异常信息
            ExceptionTracking exception = qualityManagerRepository.getExceptionTrackingByNum(exceptionNumber);
            if (exception == null) {
                return timeline;
            }
            
            // 2. 获取质检信息
            QualityInspection inspection = null;
            if (exception.getInspectionId() != null) {
                List<QualityInspection> inspections = qualityManagerRepository.queryQualityInspectionByIds(
                    Arrays.asList(exception.getInspectionId()));
                if (!inspections.isEmpty()) {
                    inspection = inspections.get(0);
                }
            }
            
            // 3. 获取原材料信息
            List<MaterialOrder> materialOrders = new ArrayList<>();
            if (inspection != null) {
                List<InspectionMaterial> inspectionMaterials = exceptionTrackingRepository.findInspectionMaterialById(inspection.getInspectionId());
                if (inspectionMaterials != null) {
                    for (InspectionMaterial material : inspectionMaterials) {
                        MaterialOrder materialOrder = exceptionTrackingRepository.findMaterialOrderById(material.getMaterialBatchId());
                        if (materialOrder != null) {
                            materialOrders.add(materialOrder);
                        }
                    }
                }
            }
            
            // 4. 获取供应商信息
            List<entity.Supplier> suppliers = new ArrayList<>();
            for (MaterialOrder materialOrder : materialOrders) {
                if (materialOrder.getSupplierId() != null) {
                    entity.Supplier supplier = qualityManagerRepository.getSupplierById(materialOrder.getSupplierId());
                    if (supplier != null && !suppliers.contains(supplier)) {
                        suppliers.add(supplier);
                    }
                }
            }
            
            // 5. 构建时间线数据（按时间倒序）
            
            // 异常发现阶段
            if (exception.getUpdateTime() != null) {
                Map<String, Object> exceptionStage = new HashMap<>();
                exceptionStage.put("timestamp", exception.getUpdateTime().format(formatter));
                exceptionStage.put("type", "danger");
                exceptionStage.put("color", "#f56c6c");
                exceptionStage.put("tagType", "danger");
                exceptionStage.put("stage", "异常发现");
                exceptionStage.put("title", "质检异常发现");
                
                List<Map<String, Object>> exceptionDetails = new ArrayList<>();
                exceptionDetails.add(createDetail("异常编号", exception.getExceptionNumber()));
                exceptionDetails.add(createDetail("异常类型", exception.getProcessType()));
                exceptionDetails.add(createDetail("报告人", exception.getReporter()));
                exceptionDetails.add(createDetail("优先级", exception.getPriority()));
                exceptionStage.put("details", exceptionDetails);
                exceptionStage.put("remark", exception.getDescription() != null ? exception.getDescription() : "异常追踪记录");
                
                timeline.add(exceptionStage);
            }
            
            // 质检阶段
            if (inspection != null && inspection.getUpdateTime() != null) {
                Map<String, Object> inspectionStage = new HashMap<>();
                inspectionStage.put("timestamp", inspection.getUpdateTime().format(formatter));
                inspectionStage.put("type", "warning");
                inspectionStage.put("color", "#e6a23c");
                inspectionStage.put("tagType", "warning");
                inspectionStage.put("stage", "质检阶段");
                inspectionStage.put("title", "质检记录");
                
                List<Map<String, Object>> inspectionDetails = new ArrayList<>();
                inspectionDetails.add(createDetail("质检ID", String.valueOf(inspection.getInspectionId())));
                inspectionDetails.add(createDetail("质检结果", inspection.getInspectResult()));
                inspectionDetails.add(createDetail("质检员", String.valueOf(inspection.getInspectorId())));
                inspectionDetails.add(createDetail("质检时间", inspection.getUpdateTime().format(formatter)));
                inspectionStage.put("details", inspectionDetails);
                inspectionStage.put("remark", inspection.getTreatment() != null ? inspection.getTreatment() : "质检记录信息");
                
                timeline.add(inspectionStage);
            }
            
            // 原材料阶段
            for (MaterialOrder materialOrder : materialOrders) {
                if (materialOrder.getUpdateTime() != null) {
                    Map<String, Object> materialStage = new HashMap<>();
                    materialStage.put("timestamp", materialOrder.getUpdateTime().format(formatter));
                    materialStage.put("type", "primary");
                    materialStage.put("color", "#409eff");
                    materialStage.put("tagType", "primary");
                    materialStage.put("stage", "原材料");
                    materialStage.put("title", "原材料信息");
                    
                    List<Map<String, Object>> materialDetails = new ArrayList<>();
                    materialDetails.add(createDetail("订单ID", String.valueOf(materialOrder.getOrderId())));
                    materialDetails.add(createDetail("材料名称", materialOrder.getMaterialName()));
                    materialDetails.add(createDetail("材料批次", materialOrder.getMaterialBatchId()));
                    materialDetails.add(createDetail("订单状态", materialOrder.getOrderStatus()));
                    materialDetails.add(createDetail("材料数量", materialOrder.getMaterialCount()));
                    materialStage.put("details", materialDetails);
                    materialStage.put("remark", "原材料采购订单信息");
                    
                    timeline.add(materialStage);
                }
            }
            
            // 供应商阶段
            for (entity.Supplier supplier : suppliers) {
                Map<String, Object> supplierStage = new HashMap<>();
                // 供应商没有updateTime，使用最早的原材料时间作为参考
                LocalDateTime supplierTime = materialOrders.isEmpty() ? LocalDateTime.now().minusDays(1) : 
                    materialOrders.get(0).getCreateTime() != null ? materialOrders.get(0).getCreateTime().minusDays(1) : LocalDateTime.now().minusDays(1);
                supplierStage.put("timestamp", supplierTime.format(formatter));
                supplierStage.put("type", "success");
                supplierStage.put("color", "#67c23a");
                supplierStage.put("tagType", "success");
                supplierStage.put("stage", "供应商");
                supplierStage.put("title", "供应商信息");
                
                List<Map<String, Object>> supplierDetails = new ArrayList<>();
                supplierDetails.add(createDetail("供应商ID", String.valueOf(supplier.getSupplierId())));
                supplierDetails.add(createDetail("供应商名称", supplier.getSupplierName()));
                supplierDetails.add(createDetail("联系方式", supplier.getContact()));
                supplierDetails.add(createDetail("供应商数量", supplier.getSupplierCount()));
                supplierDetails.add(createDetail("合格数量", supplier.getQualifyCount()));
                supplierDetails.add(createDetail("合格率", supplier.getQualityRating()));
                supplierStage.put("details", supplierDetails);
                supplierStage.put("remark", "供应商基本信息和质量评级");
                
                timeline.add(supplierStage);
            }
            
            // 不再按时间排序，保持异常、质检、原材料、供应商的顺序
            
        } catch (Exception e) {
            log.error("获取异常跟踪时间线失败: {}", e.getMessage(), e);
        }
        
        return timeline;
    }
    
    /**
     * 创建详情项
     */
    private Map<String, Object> createDetail(String label, String value) {
        Map<String, Object> detail = new HashMap<>();
        detail.put("label", label);
        detail.put("value", value != null ? value : "");
        return detail;
    }

}